package cn.minhx.domain.strategy.service.rule.tree.engine.impl;

import cn.minhx.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import cn.minhx.domain.strategy.model.valobj.tree.RuleTreeNodeLineVO;
import cn.minhx.domain.strategy.model.valobj.tree.RuleTreeNodeVO;
import cn.minhx.domain.strategy.model.valobj.tree.RuleTreeVO;
import cn.minhx.domain.strategy.service.rule.tree.ILogicTreeNode;
import cn.minhx.domain.strategy.service.rule.tree.engine.IDecisionTreeEngine;
import cn.minhx.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

/**
 * 规则决策树树实现
 *
 * @author min
 */
@Slf4j
public class DecisionTreeEngine implements IDecisionTreeEngine {

    private final Map<String, ILogicTreeNode> logicTreeNodeMap;
    private final RuleTreeVO ruleTreeVO;

    public DecisionTreeEngine(Map<String, ILogicTreeNode> logicTreeNodeMap, RuleTreeVO ruleTreeVO) {
        this.logicTreeNodeMap = logicTreeNodeMap;
        this.ruleTreeVO = ruleTreeVO;
    }

    @Override
    public DefaultTreeFactory.StrategyAwardVO process(String userId, Long strategyId, Long awardId) {

        // 获取树信息
        String nextNode = ruleTreeVO.getTreeRootRuleNode();
        Map<String, RuleTreeNodeVO> treeNodeMap = ruleTreeVO.getTreeNodeMap();

        // 根节点[记录了第一个要执行的规则]
        RuleTreeNodeVO ruleTreeNode = treeNodeMap.get(nextNode);

        // 定义决策树执行结果 - 果实
        DefaultTreeFactory.StrategyAwardVO strategyAwardVO = null;

        while (null != nextNode) {
            // 获取决策树节点
            ILogicTreeNode logicTreeNode = logicTreeNodeMap.get(ruleTreeNode.getRuleKey());

            // 决策节点计算结果
            DefaultTreeFactory.TreeActionEntity actionEntity = logicTreeNode.logic(userId, strategyId, awardId, ruleTreeNode.getRuleValue());
            RuleLogicCheckTypeVO ruleLogicCheckType = actionEntity.getRuleLogicCheckType();
            // 果实
            strategyAwardVO = actionEntity.getStrategyAwardVO();

            log.info("决策树引擎【{}】treeId:{} node:{} code:{}", ruleTreeVO.getTreeName(), ruleTreeVO.getTreeId(), nextNode, ruleLogicCheckType.getCode());

            // 获取下个节点
            nextNode = nextNode(ruleLogicCheckType.getCode(), ruleTreeNode.getTreeNodeLineVOList());
            ruleTreeNode = treeNodeMap.get(nextNode);
        }

        return strategyAwardVO;
    }

    private String nextNode(String code, List<RuleTreeNodeLineVO> treeNodeLineVOList) {
        if (null == treeNodeLineVOList || treeNodeLineVOList.isEmpty()) {
            return null;
        }
        for (RuleTreeNodeLineVO nodeLine : treeNodeLineVOList) {
            if (decisionLogic(code, nodeLine)) {
                // 返回下一个决策点
                return nodeLine.getRuleNodeTo();
            }
        }
        // 未配置下一个节点，返回null，结束
        return null;
    }

    private boolean decisionLogic(String code, RuleTreeNodeLineVO nodeLine) {
        switch (nodeLine.getRuleLimitType()) {
            case EQUAL:
                return code.equals(nodeLine.getRuleLimitValue().getCode());
            // 以下规则暂时不需要实现
            case GT:
            case GE:
            case LT:
            case LE:
            default:
                return false;
        }
    }

}
